package com.weight.common.generate.base;

import java.io.File;
import java.io.FileWriter;
import java.util.Collection;
import java.util.Iterator;

/**
*  创建java文件
*  
*/
public class JavaFile {
	protected static final String CLASS_TYPE = "class";
	protected static final String INTERFACE_TYPE = "interface";
	protected String filePath;//文件路径
	protected String fileName;//文件名
	protected String packagePath;//package 路径   package com.weight.demogenereate;
	protected String fileType;//文件类型
	protected String fileClassName;//文件名
	protected Collection<String> importPackagePaths;//导包 路径
	protected Collection<String> labelAnnotations;//标签
	protected Collection<String> extendsClass;//继承类
	protected Collection<String> implementsInterfaces;//接口
	protected Collection<Field> fieldLists;//属性
	protected Collection<Method> methodLists;//方法
	
	protected Collection<String> classDescriptionList;//文件类描述注释
	
	protected String resource;//写入数据内容
	
	protected static class Field{
    	Collection<String> annotations;//属性 标签 注解
        String modifier;//方法开放程度  public
        String fileType;//属性类型 String,Integer
        String fileClassName;// 属性业务名 id,name
        String value;//属性默认值   0 root admin
        String fileCNName;//文件中文名
        //构造器  属性无中文注释
        public Field(Collection<String> annotations, String modifier, String fileType, String fileClassName, String value){
            this.annotations = annotations;
            this.modifier = modifier;
            this.fileType = fileType;
            this.fileClassName = fileClassName;
            this.value = value;
        }
      //构造器  属性添加中文注释
        public Field(Collection<String> annotations, String modifier, String fileType, String fileClassName, String value,String fileCNName){
            this.annotations = annotations;
            this.modifier = modifier;
            this.fileType = fileType;
            this.fileClassName = fileClassName;
            this.value = value;
            this.fileCNName=fileCNName;
        }
    }
	protected static class Method{
		Collection<String> descriptionList;//描述注释
    	Collection<String> annotations;//方法 标签 注解
        String modifier;//方法开放程度  public
        String resultType;//方法返回类型
        String fileClassName;// 方法名
        String args;//方法 入参 
        Collection<String> exceptions;//抛出异常
        String methodBody;//方法体 具体实现业务
        
       //构造器
       public Method(Collection<String> annotations, String modifier, String resultType, String fileClassName, String args, Collection<String> exceptions, String methodBody){
        	this.annotations = annotations;
            this.modifier = modifier;
            this.resultType = resultType;
            this.fileClassName = fileClassName;
            this.args = args;
            this.exceptions = exceptions;
            this.methodBody = methodBody;
        }
        //有描述构造器
       public Method(Collection<String> descriptionList,Collection<String> annotations, String modifier, String resultType, String fileClassName, String args, Collection<String> exceptions, String methodBody){
	    	   this.descriptionList=descriptionList;
	    	   this.annotations = annotations;
	           this.modifier = modifier;
	           this.resultType = resultType;
	           this.fileClassName = fileClassName;
	           this.args = args;
	           this.exceptions = exceptions;
	           this.methodBody = methodBody;
       }
       public Method(Collection<String> descriptionList,Collection<String> annotations, StringBuilder modifier, StringBuilder resultType, StringBuilder fileClassName, StringBuilder args, Collection<String> exceptions, StringBuilder methodBody){
        	
        	this.descriptionList=descriptionList;
        	this.annotations = annotations;
        	if(modifier!=null)this.modifier = modifier.toString();
        	if(resultType!=null)this.resultType = resultType.toString();
        	if(fileClassName!=null)this.fileClassName = fileClassName.toString();
        	if(args!=null)this.args = args.toString();
            this.exceptions = exceptions;
            if(methodBody!=null)this.methodBody = methodBody.toString();
        } 
    }
	/**
	 * 构造器 属性初始化
	 * @param filePath
	 * @param fileName
	 * @param packagePath
	 * @param fileType
	 * @param fileClassName
	 */
    public JavaFile(String filePath, String fileName, String packagePath, String fileType, String fileClassName) {
		super();
		if(!fileType.equals("class") && !fileType.equals("interface")) {
			throw new IllegalArgumentException();
		}
		this.filePath = filePath;
		this.fileName = fileName;
		this.packagePath = packagePath;
		this.fileType = fileType;
		this.fileClassName = fileClassName;
	}
    /**
     * 构造器 属性初始化   有Class注释
     * @param filePath
     * @param fileName
     * @param packagePath
     * @param fileType
     * @param fileClassName
     * @param classDescriptionList
     */
    public JavaFile(String filePath, String fileName, String packagePath, String fileType, String fileClassName,Collection<String> classDescriptionList) {
		super();
		if(!fileType.equals("class") && !fileType.equals("interface")) {
			throw new IllegalArgumentException();
		}
		this.filePath = filePath;
		this.fileName = fileName;
		this.packagePath = packagePath;
		this.fileType = fileType;
		this.fileClassName = fileClassName;
		this.classDescriptionList = classDescriptionList;
	}
    
    /**
     * 写入数据初始化
     * @param resource
     */
    protected void init(String resource) {
    	this.resource = resource;
    }
    /**
     * Class  初始化 赋值
     * @param importPackagePaths
     * @param labelAnnotations
     * @param extendsClass
     * @param implementsInterfaces
     * @param fieldLists
     * @param methodLists
     */
    protected void init(Collection<String> importPackagePaths,
    		Collection<String> labelAnnotations,
			Collection<String> extendsClass,
    		Collection<String> implementsInterfaces,
    		Collection<Field> fieldLists,
    		Collection<Method> methodLists) {
    	this.importPackagePaths = importPackagePaths;
    	this.labelAnnotations = labelAnnotations;
    	this.extendsClass = extendsClass;
    	this.implementsInterfaces = implementsInterfaces;
    	this.fieldLists = fieldLists;
    	this.methodLists = methodLists;
    }
    /**
     * Class 初始化
     * @param importPackagePaths
     * @param labelAnnotations
     * @param extendsClass
     * @param implementsInterfaces
     * @param fieldLists
     * @param methodLists
     * @param classDescriptionList
     */
    protected void init(Collection<String> importPackagePaths,
    		Collection<String> labelAnnotations,
			Collection<String> extendsClass,
    		Collection<String> implementsInterfaces,
    		Collection<Field> fieldLists,
    		Collection<Method> methodLists,Collection<String> classDescriptionList) {
    	this.importPackagePaths = importPackagePaths;
    	this.labelAnnotations = labelAnnotations;
    	this.extendsClass = extendsClass;
    	this.implementsInterfaces = implementsInterfaces;
    	this.fieldLists = fieldLists;
    	this.methodLists = methodLists;
    	this.classDescriptionList = classDescriptionList;
    }
    /**
     * 创建文件路径 文件夹
     * @return
     * @throws Exception
     */
    protected File makeJavaDir() throws Exception{
        synchronized (JavaFile.class) {
            File dir = new File(filePath);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            return dir;
        }
    }
    /**
     * 创建.java文件
     * @return
     * @throws Exception
     */
    protected File makeJavaFile() throws Exception{
        synchronized (JavaFile.class) {
            File dir = makeJavaDir();
            if (!fileName.endsWith(".java")) {
                fileName += ".java";
            }
            File file = new File(dir, fileName);
            if (!file.exists()) {
                file.createNewFile();
            }
            return file;
        }
    }
    public void generate() throws Exception{
        //创建文件及文件夹
        File file = makeJavaFile();
        FileWriter fileWriter = new FileWriter(file);
        //创建写入数据源
        StringBuilder stringBuilder = new StringBuilder();
        //写入 包位置
        stringBuilder.append("package ");
        stringBuilder.append(packagePath);
        stringBuilder.append(";\n\n");
        
        //写入导包
        if(importPackagePaths != null) {
            Iterator<String> iterator = importPackagePaths.iterator();
            while (iterator.hasNext()) {
                stringBuilder.append("import ");
                stringBuilder.append(iterator.next());
                stringBuilder.append(";\n");
            }
        }
        stringBuilder.append("\n");
        
        
      //描述注释
        if(classDescriptionList!=null){
            Iterator<String> classDecLists = classDescriptionList.iterator();
            while(classDecLists.hasNext()) {
//                stringBuilder.append("\t");
                stringBuilder.append(classDecLists.next());
                stringBuilder.append("\n");
            }
        }
        
        
  //写引入标签
        if(labelAnnotations != null){
            Iterator<String> iterator = labelAnnotations.iterator();
            while(iterator.hasNext()){
            	stringBuilder.append("@");
            	stringBuilder.append(iterator.next());
            	stringBuilder.append("\n");
            }
        }
        //写   类名  或  接口名 
        stringBuilder.append("public "+fileType+" "+fileClassName+" ");
        //写 继承
        if(extendsClass != null) {
	        Iterator<String> iterator = extendsClass.iterator();
	        int count = 0;
	        while(iterator.hasNext()) {
	        	if(count==0) {
	        		stringBuilder.append("extends ");
	        	}else {
	        		stringBuilder.append(",");
	        	}
	        	stringBuilder.append(iterator.next());
	        	count++;
	        }
	        if(count > 0) {
	        	stringBuilder.append(" ");
	        }
        }
 //写  实现接口
        if(implementsInterfaces != null) {
	        Iterator<String> iterator = implementsInterfaces.iterator();
	        int count = 0;
	        while(iterator.hasNext()) {
	        	if(count==0) {
	        		stringBuilder.append("implements ");
	        	}else {
	        		stringBuilder.append(",");
	        	}
	        	stringBuilder.append(iterator.next());
	        	count++;
	        }
	        if(count > 0) {
	        	stringBuilder.append(" ");
	        }
        }
        stringBuilder.append("{\n\n");
        
 //属性书写
        if(fieldLists != null) {
            Iterator<Field> iterator = fieldLists.iterator();
            while (iterator.hasNext()) {
                Field field = iterator.next();
                if(field.annotations!=null){
                    Iterator<String> iteratorAnnotations = field.annotations.iterator();
                    while(iteratorAnnotations.hasNext()) {
                        stringBuilder.append("\t");
                        stringBuilder.append("@");
                        stringBuilder.append(iteratorAnnotations.next());
                        stringBuilder.append("\n");
                    }
                }
                if(field.modifier!=null){
                    stringBuilder.append("\t");
                    stringBuilder.append(field.modifier);
                    stringBuilder.append(" ");
                }
                if(field.fileType!=null){
                    stringBuilder.append(field.fileType);
                    stringBuilder.append(" ");
                }
                if(field.fileClassName!=null){
                    stringBuilder.append(field.fileClassName);
                }
                if(field.value!=null){
                    stringBuilder.append(" = ");
                    stringBuilder.append(field.value);
                }
                stringBuilder.append(";");
                
                if(field.fileCNName!=null){
                    stringBuilder.append(" //");
                    stringBuilder.append(field.fileCNName);
                }
                stringBuilder.append("\n\n");
            }
            stringBuilder.append("\n");
        }
        
        //方法书写
        if(fileType.equals("class")) {
	        if(methodLists != null) {
	            Iterator<Method> iterator = methodLists.iterator();
	            while (iterator.hasNext()) {
	                Method method = iterator.next();
	                
	              //描述注释
	                if(method.descriptionList!=null){
	                    Iterator<String> descriptionLists = method.descriptionList.iterator();
	                    while(descriptionLists.hasNext()) {
	                        stringBuilder.append("\t");
	                        stringBuilder.append(descriptionLists.next());
	                        stringBuilder.append("\n");
	                    }
	                }
	              //方法 标签 注解
	                if(method.annotations!=null){
	                    Iterator<String> iteratorAnnotations = method.annotations.iterator();
	                    while(iteratorAnnotations.hasNext()) {
	                        stringBuilder.append("\t@");
	                        stringBuilder.append(iteratorAnnotations.next());
	                        stringBuilder.append("\n");
	                    }
	                }
	              //方法开发程度  public
	                if(method.modifier!=null){
	                    stringBuilder.append("\t");
	                    stringBuilder.append(method.modifier);
	                    stringBuilder.append(" ");
	                }
	              //方法返回类型
	                if(method.resultType!=null){
	                    stringBuilder.append(method.resultType);
	                    stringBuilder.append(" ");
	                }
	             // 方法名
	                if(method.fileClassName!=null){
	                    stringBuilder.append(method.fileClassName);
	                }
	                stringBuilder.append("(");
	              //方法 入参 
	                if(method.args!=null){
	                    stringBuilder.append(method.args);
	                }
	                stringBuilder.append(")");
	                //抛出异常
	                if(method.exceptions!=null){
	                    Iterator<String> iteratorExceptions = method.exceptions.iterator();
	                    int count = 0;
	                    while(iteratorExceptions.hasNext()) {
	                        if(count == 0){
	                            stringBuilder.append(" throws ");
	                        }else{
	                            stringBuilder.append(",");
	                        }
	                        stringBuilder.append(iteratorExceptions.next());
	                        count++;
	                    }
	                }
	                stringBuilder.append("{\n");
	                //方法体 具体实现业务
	                if(method.methodBody!=null){
	                    stringBuilder.append(method.methodBody);
	                }
	                stringBuilder.append("\t}\n\n");
	            }
	        }
        }else if(fileType.equals("interface")) {//接口书写
	        if(methodLists != null) {
	            Iterator<Method> iterator = methodLists.iterator();
	            while (iterator.hasNext()) {
	                Method method = iterator.next();
	              //描述注释
	                if(method.descriptionList!=null){
	                    Iterator<String> descriptionLists = method.descriptionList.iterator();
	                    while(descriptionLists.hasNext()) {
	                        stringBuilder.append("\t");
	                        stringBuilder.append(descriptionLists.next());
	                        stringBuilder.append("\n");
	                    }
	                }
	                if(method.modifier!=null){
	                    stringBuilder.append("\t");
	                    stringBuilder.append(method.modifier);
	                    stringBuilder.append(" ");
	                }
	                if(method.resultType!=null){
	                    stringBuilder.append(method.resultType);
	                    stringBuilder.append(" ");
	                }
	                if(method.fileClassName!=null){
	                    stringBuilder.append(method.fileClassName);
	                    stringBuilder.append("(");
	                }
	                if(method.args!=null){
	                    stringBuilder.append(method.args);
	                    stringBuilder.append(")");
	                }
	                if(method.exceptions!=null){
	                    Iterator<String> iteratorExceptions = method.exceptions.iterator();
	                    int count = 0;
	                    while(iteratorExceptions.hasNext()) {
	                        if(count == 0){
	                            stringBuilder.append(" throws ");
	                        }else{
	                            stringBuilder.append(",");
	                        }
	                        stringBuilder.append(iteratorExceptions.next());
	                        count++;
	                    }
	                }
	                stringBuilder.append(";\n\n");
	            }
	        }
        }
        //类或接口结束
        stringBuilder.append("}");
        //开始写入
        fileWriter.write(stringBuilder.toString());
        //关闭写入
        fileWriter.flush();
        fileWriter.close();
    }
    
    public void personalGenerate() throws Exception {
    	//创建文件及文件夹
        File file = makeJavaFile();
        FileWriter fileWriter = new FileWriter(file);
        //创建写入数据源
        StringBuilder stringBuilder = new StringBuilder();
        //写入 包位置
        stringBuilder.append("package ");
        stringBuilder.append(packagePath);
        stringBuilder.append(";\n\n");
        //写入数据源
        if(resource != null) {
        	stringBuilder.append(resource);
        }
        //开始写入
        fileWriter.write(stringBuilder.toString());
        //关闭写入
        fileWriter.flush();
        fileWriter.close();
    }
    
    
    public static StringBuilder getModelClass(String model) {
	    if(model!=null&&!model.equals("")) {
	    	char[] ch = model.toCharArray();  
		    if (ch[0] >= 'a' && ch[0] <= 'z') {  
		        ch[0] = (char) (ch[0] - 32);  
		    }  
			StringBuilder modelClass = new StringBuilder(new String(ch));
			return modelClass;
	    }else {
	    	return null;
	    }
	}
  //导入实体类拼接
	public static StringBuilder getImportName(String packagePath,String model) {
		StringBuilder importName = new StringBuilder();
		importName.append(packagePath);
		importName.append(".PO.");
		importName.append(getModelClass(model));
		return importName;
	}
	public static StringBuilder getImportName(String packagePath,String and,String name) {
		StringBuilder importName = new StringBuilder();
		importName.append(packagePath);
		importName.append(".");
		importName.append(and);
		importName.append(".");
		importName.append(getModelClass(name));
		return importName;
	}
}
